package dao

import (
	"fmt"

	"gorm.io/gorm"
	"openeuler.org/PilotGo/PilotGo-plugin-automation/internal/global"
	"openeuler.org/PilotGo/PilotGo-plugin-automation/internal/module/common/enum/script"
	"openeuler.org/PilotGo/PilotGo-plugin-automation/internal/module/script_library/model"
	"openeuler.org/PilotGo/PilotGo-plugin-automation/pkg/response"
	"openeuler.org/PilotGo/PilotGo-plugin-automation/pkg/utils"
)

func AddScript(script *model.Script, scriptVersion *model.ScriptVersion) error {
	return global.App.MySQL.Transaction(func(tx *gorm.DB) error {
		if err := tx.Create(script).Error; err != nil {
			return err
		}

		if err := tx.Create(scriptVersion).Error; err != nil {
			return err
		}

		return nil
	})
}

func GetScripts(query *response.PagedQuery, name, script_type, tag, usage_type string) ([]*model.ScriptResponse, int, error) {
	var scripts []*model.Script
	var scriptResponses []*model.ScriptResponse
	var total int64
	q := global.App.MySQL.Model(&model.Script{})
	qc := global.App.MySQL.Model(&model.Script{})

	if query.Search != "" {
		if utils.IsDsl(query.Search) {
			q = q.Where(query.Search)
			qc = qc.Where(query.Search)
		} else {
			searchValue := query.Search
			q = q.Where("name LIKE ? OR tag LIKE ? OR script_type LIKE ? OR usage_type LIKE ?",
				"%"+searchValue+"%", "%"+searchValue+"%", fmt.Sprintf("%%%d%%", script.ParseScriptType(searchValue)), "%"+searchValue+"%")
			qc = qc.Where("name LIKE ? OR tag LIKE ? OR script_type LIKE ? OR usage_type LIKE ?",
				"%"+searchValue+"%", "%"+searchValue+"%", fmt.Sprintf("%%%d%%", script.ParseScriptType(searchValue)), "%"+searchValue+"%")
		}
	}

	if len(name) != 0 {
		q = q.Where("name = ?", name)
		qc = qc.Where("name = ?", name)
	}

	if len(script_type) != 0 {
		q = q.Where("script_type = ?", script.ParseScriptType(script_type))
		qc = qc.Where("script_type = ?", script.ParseScriptType(script_type))
	}

	if len(tag) != 0 {
		q = q.Where("tag = ?", tag)
		qc = qc.Where("tag = ?", tag)
	}

	if len(usage_type) != 0 {
		q = q.Where("usage_type = ?", usage_type)
		qc = qc.Where("usage_type = ?", usage_type)
	}

	if err := q.Limit(query.PageSize).Offset((query.CurrentPage - 1) * query.PageSize).Order("modify_time desc").Find(&scripts).Error; err != nil {
		return nil, 0, err
	}
	// 组装 ScriptResponse
	for _, s := range scripts {
		sr := &model.ScriptResponse{
			ID:                      s.ID,
			Name:                    s.Name,
			ScriptType:              s.ScriptType.String(),
			UsageType:               s.UsageType,
			Description:             s.Description,
			RelatedTaskWorkflowNum:  s.RelatedTaskWorkflowNum,
			RelatedTaskOperationNum: s.RelatedTaskOperationNum,
			VersionOnline:           s.VersionOnline,
			ModifyUser:              s.ModifyUser,
			ModifyTime:              s.ModifyTime,
		}

		var tag model.Tag
		if len(s.Tag) > 0 {
			if err := global.App.MySQL.Model(&model.Tag{}).Where("name = ?", s.Tag).Find(&tag).Error; err != nil {
				return nil, 0, err
			}
		}
		sr.Tag = tag

		scriptResponses = append(scriptResponses, sr)
	}

	if err := qc.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	return scriptResponses, int(total), nil
}

func UpdateScript(id string, s *model.Script) error {
	return global.App.MySQL.Model(&model.Script{}).Where("id = ?", id).Updates(s).Error
}

func DeleteScript(id string) error {
	return global.App.MySQL.Transaction(func(tx *gorm.DB) error {
		if err := tx.Where("script_id = ?", id).Delete(&model.ScriptVersion{}).Error; err != nil {
			return err
		}

		if err := tx.Where("id = ?", id).Delete(&model.Script{}).Error; err != nil {
			return err
		}
		return nil
	})
}

func RelatedScriptNum(scriptId string) (relatedTaskWorkflowNum int, relatedTaskOperationNum int, err error) {
	var script model.Script
	err = global.App.MySQL.Model(&model.Script{}).
		Where("id = ?", scriptId).
		Find(&script).Error
	if err != nil {
		return
	}

	relatedTaskWorkflowNum = script.RelatedTaskWorkflowNum
	relatedTaskOperationNum = script.RelatedTaskOperationNum
	return
}
